package lgvalle.com.fluxtodo.flux.stores;


import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import lgvalle.com.fluxtodo.flux.fluxbase.Action;
import lgvalle.com.fluxtodo.flux.actions.TodoActions;
import lgvalle.com.fluxtodo.flux.fluxbase.Dispatcher;
import lgvalle.com.fluxtodo.flux.fluxbase.Store;
import lgvalle.com.fluxtodo.model.Todo;

import javax.inject.Inject;

/**
 * Created by lgvalle on 02/08/15.
 */
public class TodoStore extends Store {

    // datas: todos
    private final List<Todo> todos;
    // 最近删除的一个todo
    private Todo lastDeleted;


    // 构造方法 依赖注入构造器
    @Inject
    public TodoStore(Dispatcher dispatcher) {
        super(dispatcher);
        todos = new ArrayList<>();
    }

    // 获取datas todos
    public List<Todo> getTodos() {
        return todos;
    }

    // 是否可以undo
    public boolean canUndo() {
        return lastDeleted != null;
    }


    // 根据收到的action来处理业务逻辑
    @Override
     protected void onActionReceive(Action action) {
        long id;
        switch (action.getType()) {
            case TodoActions.TODO_CREATE:
                String text = (String) action.getData(TodoActions.KEY_TEXT);
                create(text);
                changeEvent();
                break;

            case TodoActions.TODO_DESTROY:
                id = (long) action.getData(TodoActions.KEY_ID);
                destroy(id);
                changeEvent(true);
                break;

            case TodoActions.TODO_UNDO_DESTROY:
                undoDestroy();
                changeEvent();
                break;

            case TodoActions.TODO_COMPLETE:
                id = (long) action.getData(TodoActions.KEY_ID);
                updateComplete(id, true);
                changeEvent();
                break;

            case TodoActions.TODO_UNDO_COMPLETE:
                id = (long) action.getData(TodoActions.KEY_ID);
                updateComplete(id, false);
                changeEvent();
                break;

            case TodoActions.TODO_DESTROY_COMPLETED:
                destroyCompleted();
                changeEvent();
                break;

            case TodoActions.TODO_TOGGLE_COMPLETE_ALL:
                updateCompleteAll();
                changeEvent();
                break;
        }
    }

    // 删除已经完成的todo的方法
    private void destroyCompleted() {
        Iterator<Todo> iter = todos.iterator();
        while (iter.hasNext()) {
            Todo todo = iter.next();
            if (todo.isComplete()) {
                iter.remove();
            }
        }
    }

    // 全部todo的开关,全部完成了则 全部设置未打开 .否则 全部完成
    private void updateCompleteAll() {
        if (areAllComplete()) {
            updateAllComplete(false);
        } else {
            updateAllComplete(true);
        }
    }

    // 是否所有都完成了
    private boolean areAllComplete() {
        for (Todo todo : todos) {
            if (!todo.isComplete()) {
                return false;
            }
        }
        return true;
    }

    // 设置所有完成情况
    private void updateAllComplete(boolean complete) {
        for (Todo todo : todos) {
            todo.setComplete(complete);
        }
    }

    // 根据id来设置完成情况
    private void updateComplete(long id, boolean complete) {
        Todo todo = getById(id);
        if (todo != null) {
            todo.setComplete(complete);
        }
    }

    // undo一个最近删除的todo
    private void undoDestroy() {
        if (lastDeleted != null) {
            // 存在的话 clone一份
            addElement(lastDeleted.clone());
            // 清除
            lastDeleted = null;
        }
    }

    // 创建一个todo
    private void create(String text) {
        // 当前时间作为id
        long id = System.currentTimeMillis();
        Todo todo = new Todo(id, text);
        addElement(todo);
        // 使用时间来排序
        Collections.sort(todos);
    }

    // 根据id删除一个todo
    private void destroy(long id) {
        Iterator<Todo> iter = todos.iterator();
        while (iter.hasNext()) {
            Todo todo = iter.next();
            if (todo.getId() == id) {
                lastDeleted = todo.clone();
                iter.remove();
                break;
            }
        }
    }

    // 通过id来获取一个todo
    private Todo getById(long id) {
        Iterator<Todo> iter = todos.iterator();
        while (iter.hasNext()) {
            Todo todo = iter.next();
            if (todo.getId() == id) {
                return todo;
            }
        }
        return null;
    }
    // 添加一个todo 并且排序
    private void addElement(Todo clone) {
        todos.add(clone);
        Collections.sort(todos);
    }

    void changeEvent(boolean showSnake) {
        TodoStoreChangeEvent event = new TodoStoreChangeEvent();
        event.needShowDeleteSnake = showSnake;
        notifyStoreChanged(event);
    }
    void changeEvent() {
        changeEvent(false);
    }

    // 每个不同store的不同changevent
    public class TodoStoreChangeEvent implements StoreChangeEvent {
        public boolean needShowDeleteSnake;
    }
}
